package org.ssssssss.example.scheduled;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.Objects;

public class SchedulingRunnable implements Runnable {
    private static final Logger logger = LoggerFactory.getLogger(SchedulingRunnable.class);

    private final String BEAN_NAME = "magicAPIService";

    private String apiType = "execute";

    private String methodName;

    private String path;

    private String params;

    public SchedulingRunnable(String apiType, String methodName, String path, String params) {
        this.apiType = apiType;
        this.methodName = methodName;
        this.path = path;
        this.params = params;
    }

    //执行任务的方式为接口
    public SchedulingRunnable(String methodName, String path, String params) {
        this.apiType = "execute";
        this.methodName = methodName;
        this.path = path;
        this.params = params;
    }

    //执行任务的方式为函数时
    public SchedulingRunnable(String path, String params) {
        this.apiType = "invoke";
        this.path = path;
        this.params = params;
    }

    @Override
    public void run() {
        logger.info("定时任务开始执行 >> 执行类型：{}, 接口方法：{},接口地址：{},参数：{}", apiType, methodName, path, params);
        long startTime = System.currentTimeMillis();
        try {
            Object target = SpringContextUtils.getBean(BEAN_NAME);
            Method method = null;
            if (apiType.equalsIgnoreCase("invoke")) {
                method = target.getClass().getDeclaredMethod(apiType, String.class, Map.class);
            } else {
                method = target.getClass().getDeclaredMethod(apiType, String.class, String.class, Map.class);
            }
            ReflectionUtils.makeAccessible(method);
            Map maps;
            if (StringUtils.isNotEmpty(params)) {
                maps = (Map) JSON.parse(params);
            } else {
                maps = null;
            }
            if (apiType.equalsIgnoreCase("invoke")) {
                method.invoke(target, path, maps);
            } else {
                method.invoke(target, methodName, path, maps);
            }
        } catch (Exception ex) {
            logger.error(String.format("定时任务执行异常 >> 执行类型：%s，接口方法：%s，接口地址：%s，参数：%s", apiType, methodName, path, params), ex);
        }

        long times = System.currentTimeMillis() - startTime;
        logger.info("定时任务执行结束 >> 执行类型：{}, 接口方法：{},接口地址：{},参数：{}，耗时：{} 毫秒", apiType, methodName, path, params, times);
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        SchedulingRunnable that = (SchedulingRunnable) o;
        return Objects.equals(apiType, that.apiType) &&
                Objects.equals(methodName, that.methodName) &&
                Objects.equals(path, that.path) &&
                Objects.equals(params, that.params);
    }

    @Override
    public int hashCode() {
        return Objects.hash(apiType, methodName, path, params);
    }
}
